package com.jdrx.sw.sewage.service;

import com.alibaba.fastjson.JSONObject;
import com.jdrx.sw.sewage.common.enums.EWebSocketType;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/webSocket/{ws_username}")
public class WebSocketServiceImpl {
    private static int gys_onlineCount = 0;
    private static int gy_onlineCount = 0;
    private static int gjs_onlineCount = 0;
    private static Map<String, WebSocketServiceImpl> gys_clients = new ConcurrentHashMap<String, WebSocketServiceImpl>();
    private static Map<String, WebSocketServiceImpl> gy_clients = new ConcurrentHashMap<String, WebSocketServiceImpl>();
    private static Map<String, WebSocketServiceImpl> gjs_clients = new ConcurrentHashMap<String, WebSocketServiceImpl>();
    private Session session;
    private String username;

    public static synchronized int getOnlineCount(String type) {
        if (EWebSocketType.GYS.getKey().equals(type)) return gys_onlineCount;
        if (EWebSocketType.GY.getKey().equals(type)) return gy_onlineCount;
        if (EWebSocketType.GJS.getKey().equals(type)) return gjs_onlineCount;
        return 0;
    }

    public static synchronized void addOnlineCount(String type) {
        if (EWebSocketType.GYS.getKey().equals(type)) WebSocketServiceImpl.gys_onlineCount++;
        if (EWebSocketType.GY.getKey().equals(type)) WebSocketServiceImpl.gy_onlineCount++;
        if (EWebSocketType.GJS.getKey().equals(type)) WebSocketServiceImpl.gjs_onlineCount++;
    }

    public static synchronized void subOnlineCount(String type) {
        if (EWebSocketType.GYS.getKey().equals(type)) WebSocketServiceImpl.gys_onlineCount--;
        if (EWebSocketType.GY.getKey().equals(type)) WebSocketServiceImpl.gy_onlineCount--;
        if (EWebSocketType.GJS.getKey().equals(type)) WebSocketServiceImpl.gjs_onlineCount--;
    }

    public static synchronized Map<String, WebSocketServiceImpl> getClients(String type) {
        if (EWebSocketType.GYS.getKey().equals(type)) return gys_clients;
        if (EWebSocketType.GY.getKey().equals(type)) return gy_clients;
        if (EWebSocketType.GJS.getKey().equals(type)) return gjs_clients;
        return null;
    }

    @OnOpen
    public void onOpen(@PathParam("ws_username") String username, Session session) {
        this.username = username;
        this.session = session;

        String type = username.split("_")[0];
        addOnlineCount(type);
        if (EWebSocketType.GYS.getKey().equals(type)) gys_clients.put(username, this);
        if (EWebSocketType.GY.getKey().equals(type)) gy_clients.put(username, this);
        if (EWebSocketType.GJS.getKey().equals(type)) gjs_clients.put(username, this);
    }

    @OnClose
    public void onClose() {
        String type = username.split("_")[0];
        if (EWebSocketType.GYS.getKey().equals(type)) gys_clients.remove(username);
        if (EWebSocketType.GY.getKey().equals(type)) gy_clients.remove(username);
        if (EWebSocketType.GJS.getKey().equals(type)) gjs_clients.remove(username);
        subOnlineCount(type);
    }

    @OnMessage
    public void onMessage(String message) {
        JSONObject jsonTo = JSONObject.parseObject(message);
        String mes = (String) jsonTo.get(EWebSocketType.MESSAGE.getKey());
        String type = jsonTo.get(EWebSocketType.ALL.getKey()).toString();
        String to = jsonTo.get(EWebSocketType.TO.getKey()).toString();

        if (!to.equals(EWebSocketType.ALL.getKey())) sendMessageTo(mes, to, type);
        else sendMessageAll(mes, type);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    public void sendMessageTo(String message, String to, String type) {
        /*Collection<WebSocketServiceImpl> values = null;
        if (EWebSocketType.GY.getKey().equals(type)) values = gy_clients.values();
        if (EWebSocketType.GJS.getKey().equals(type)) values = gjs_clients.values();
        values.stream().forEach(item -> {
            if (item.username.equals(to)) item.session.getAsyncRemote().sendObject(message);
        });*/
        WebSocketServiceImpl webSocket = null;
        if (EWebSocketType.GYS.getKey().equals(type)) webSocket = gys_clients.get(to);
        if (EWebSocketType.GY.getKey().equals(type)) webSocket = gy_clients.get(to);
        if (EWebSocketType.GJS.getKey().equals(type)) webSocket = gjs_clients.get(to);
        webSocket.session.getAsyncRemote().sendObject(message);
    }

    public void sendMessageAll(String message, String type) {
        Collection<WebSocketServiceImpl> webSockets = null;
        if (EWebSocketType.GYS.getKey().equals(type)) webSockets = gys_clients.values();
        if (EWebSocketType.GY.getKey().equals(type)) webSockets = gy_clients.values();
        if (EWebSocketType.GJS.getKey().equals(type)) webSockets = gjs_clients.values();
        webSockets.stream().forEach(webSocket -> {
            webSocket.session.getAsyncRemote().sendObject(message);
        });
    }
}